import { clamp, Color, MeshRenderer, Node, Quat, SkeletalAnimation, toRadian, Vec3, _decorator } from 'cc';
import { Debug } from './core/Debug';
import { Object3D } from './Object3D';
import { aa } from '../frame/FrameCore';
import ctrlMgr from '../frame/input/InputCtrl';
import { BuildCtrl } from '../deco/BuildCtrl';
import world from './World';

let moveUp = new Vec3();
let pos = new Vec3();
const { ccclass, property } = _decorator;

@ccclass('Player')
export class Player extends Object3D {

    @property
    boundDebug: boolean = false;

    @property(Node)
    target: Node;

    @property(SkeletalAnimation)
    character: SkeletalAnimation = null;

    @property({ min: 0 })
    maxSpeed: number = 10;

    angle: number = 0;
    vertical: number = 0;
    velocity: Vec3 = new Vec3();
    direction: Vec3 = new Vec3(0, 0, 0);
    surfaceNormal: Vec3 = new Vec3(0, 1, 0);

    sample: number = 0;
    isMove: boolean = false;
    rayDir: Vec3 = new Vec3();
    private _currAni: string = null;
    private _rot: Quat = new Quat();
    private _isMove = false;

    isRayCast: boolean = false;

    start() {
        this.preBuild();

    }

    init() {
        if (this.boundDebug) {
            let node = new Node("DebugCollider");
            let render = node.addComponent(MeshRenderer);
            render.mesh = this.meshCollider;
            this.node.addChild(node);
        }
        // world.clear()
        world.preBuild(BuildCtrl.ins.node);
    }

    protected onDisable(): void {

        this.stop();
        world.clear();

    }

    stop() {


        this.isMove = false;
        world.clear();
    }

    reset() {
        this.changeAnimation("idle");
        this.node.position = new Vec3(0, 2, 0);
        this.node.rotation = Quat.IDENTITY;
        this.surfaceNormal.set(0, 1, 0);
        this.velocity.set(Vec3.ZERO);
        // this.angle = 0;
    }

    changeAnimation(name: string) {
        if (this.character && this._currAni != name) {
            this._currAni = name;
            this.character.crossFade(name, 0.5);
        }
    }

    rotateCharacter(angle: number) {
        if (this.character) {
            //this.character.getState(this._currAni).speed = clamp(ratio,0.5,1.0);
            this.character.node.rotation = Quat.fromAxisAngle(this._rot, Vec3.UNIT_Y, angle + Math.PI / 2);
        }
    }


    checkInput() {
        const h = ctrlMgr.h;
        const v= ctrlMgr.v;

        if (h==0 && v==0) {
            this.isMove = false;
            this.changeAnimation("idle");
        } else {
            let angle = Math.atan2(h, v);
        let ratio = ctrlMgr.ratio;

            this.isMove = true;
            let speed = this.maxSpeed * ratio;
            // 修正：获取相机的 Y 轴旋转角度
            let cameraYRotation = aa.global.orbitCam.node.eulerAngles.y;

            // 将摇杆角度转换为世界坐标系角度
            let worldAngle = toRadian(cameraYRotation) + angle;

            // 计算移动方向
            this.direction.set(
                Math.cos(worldAngle) * speed,
                0,
                -Math.sin(worldAngle) * speed
            );

            this.rayDir.set(this.direction);
            this.rotateCharacter(worldAngle);
            this.changeAnimation("run");
        }

    }



    update(dt: number) {
        this.checkInput();
        if (!this.isMove) return;
        dt = clamp(dt, 0.0, 0.016 * 2);
        Vec3.copy(pos, this.node.position)
        let v = this.direction
        pos.x = pos.x + (v.x * dt);
        pos.z = pos.z + (v.z * dt);
        this.setPosition(pos);
        let isCollision = false;
        let collisions = world.objectQuery(this, true);
        const cl = collisions.length
        for (let i = 0; i < cl; i++) {
            let obj = collisions[i];
            let result = world.collision.GJK(this, obj);
            if (result) {
                let dir = result.dir;
                let dist = result.dist;
                moveUp.set(dir).multiplyScalar(dist);
                moveUp.y = 0;
                this.setPosition(pos.add(moveUp));
                isCollision = true;
                if (obj.obj3D.debug)
                    Debug.addBox(obj.getWorldBound(), obj.isBox ? Color.RED : Color.CYAN);
            }
        }
        // this.checkRays();
    }
}

